﻿package com.tools
{
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import com.tools.notifications.XmlEvent;
	import com.tools.notifications.AvailableDataEvent;
	import com.main.CustomDispatcher;
	import com.utils.VOConverterUtils;
	import com.conf.PlayerSpec;
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////
	// XmlParser ::
	// - cette classe gère le parsing des fichiers xml
	// - on étend CustomDispatcher pour pouvoir aisément dispatcher des events persos
	/////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	public class XmlParser extends CustomDispatcher
	{		
		// référence au Model
		private var model						: Object;
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////
		// METHODE PUBLIQUE : CONSTRUCTION DU LAYOUT A PARTIR DES DONNEES PARSEES DU XML
		/////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public function buildSkinModel ( pEvt : XmlEvent, pModel : Object )
		{
			// on recense le Controller auprès du parser
			this.model 	= pModel;
			// sert à ignorer les espaces potentiellement présents dans le fichier xml
			XML.ignoreWhitespace = true;
			// on crée l'objet temporaire qui reçoit, une fois parsé, toutes les infos depuis le xml
			var aObject		: Object;
			aObject = new Object();
			// on crée une variable d'ordre de position
			var aPosition	: Number = 2;
			// extrait le xml à partir de l'event
			var templateInfos	: XML 		= new XML ( pEvt.infos );
			// variables utilisées dans la boucle de création du model de skin :
			// aPW : référence au widget parent dans la boucle
			var aPW 			: int	 	= 1;
			// aPC : référence au composant parent dans la boucle
			var aPC 			: int	 	= 1;
			// aPE : référence à l'élément parent dans la boucle
			var aPE				: int;
			
			// on extrait les noeuds du xml
			var fNode 			: XMLList 	= templateInfos.*;
			// référence au noeud de widget parsé
			var wNode 			: XMLList;
			// référence au noeud de composant parsé
			var cNode 			: XMLList;
			// référence au noeud en cours de parsage
			var currentNode		: Number;
			
			// pour chacun des noeuds du xml
			for each ( var node : XML in fNode )
			{
				// on crée un nouvel objet pour accueillir les informations parsées
				// différement selon le type de noeud parsé : widget (PlayerSpec.GLOBAL_CONTAINER ou autre) / composant / élément
				if( node.localName() == PlayerSpec.NODE_WIDGET)
				{	
					if ( node.@[PlayerSpec.ATTRIBUTE_NAME_WIDGET] == PlayerSpec.CONTAINER_GLOBAL )
					{
						aObject = VOConverterUtils.createWidgetObject(
																				node.@[PlayerSpec.ATTRIBUTE_NAME_WIDGET],
																				node.localName(),
																				0,
																				1
																				);
					}
					else
					{
						aObject = VOConverterUtils.createWidgetObject(
																		node.@[PlayerSpec.ATTRIBUTE_NAME_WIDGET],
																		node.localName(),
																		1,
																		aPosition
																		);
						
						// une fois le noeud widget parcouru, on référence la position en tant que valeur du noeud widget parent
						aPW		 			= aPosition; 
						// on incrémente la position
						aPosition++;
					}
					// on ajoute l'objet de propriété à la skin
					this.model.addSkin ( aObject );
					
					////////////////////////////////////////////////
					// ON BOUCLE A L'INTERIEUR DES NOEUDS DU WIDGET
					////////////////////////////////////////////////
					
					// on référence le contenu du noeud widget
					wNode = node.*;
					
					// pour, à son tour, le parser
					for each( var nodechild : XML in wNode )
					{
						
						if( nodechild.localName() == PlayerSpec.NODE_COMPONENT )
						{
							aObject = VOConverterUtils.createSimpleComponentObject(
																		nodechild.@[PlayerSpec.ATTRIBUTE_NAME_COMPONENT],
																		nodechild.localName(),
																		aPW,
																		aPosition
																		);
							this.model.skinsList[this.model.skinsList.length-1].skinContentList.push ( aObject );
							aPC = aPosition;
							aPosition++;
							
							////////////////////////////////////////////////
							// ON BOUCLE A L'INTERIEUR DES NOEUDS DU COMPOSANT
							////////////////////////////////////////////////
							
							cNode = nodechild.*;
							
						
							for each ( var nodegdchild : XML in cNode )
							{								
								if( nodegdchild.localName() == PlayerSpec.NODE_ELEMENT )
								{
									aObject = VOConverterUtils.createElementObject(
																		nodegdchild.@[PlayerSpec.ATTRIBUTE_NAME_ELEMENT],
																		nodegdchild.localName(),
																		aPC,
																		aPosition,
																		nodegdchild.@[PlayerSpec.ATTRIBUTE_WIDTH],
																		nodegdchild.@[PlayerSpec.ATTRIBUTE_HEIGHT],
																		nodegdchild.@[PlayerSpec.ATTRIBUTE_X],
																		nodegdchild.@[PlayerSpec.ATTRIBUTE_Y],
																		nodegdchild.@[PlayerSpec.ATTRIBUTE_URL],
																		this.model.currentSkin
																		);
									trace( "génération de l'url :: \n" + nodegdchild.@[PlayerSpec.ATTRIBUTE_URL] + "\n----" );
									var lng : uint = this.model.skinsList.length-1;
									var lng2 : uint = this.model.skinsList[lng].skinContentList.length-1;
									this.model.skinsList[lng].skinContentList[lng2].skinContentList.push( aObject );
									
									aPE = aPosition;
									aPosition++;
								}
							}
						}
					}
				}
			}
			// on lance l'événement qui annonce que la skin est désormais disponible
			dispatchEvent ( new AvailableDataEvent ( AvailableDataEvent.SKIN_DATA_READY, true, false ) );
		}
	}
}